using System.Collections.Concurrent;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using SeataNet.Core.Common;
using SeataNet.Core.Model;
using SeataNet.Core.RPC;
using SeataNet.Core.Monitor;

namespace SeataNet.Core.Protocol
{
    /// <summary>
    /// 消息类型枚举
    /// </summary>
    public enum MessageType
    {
        // TC -> TM
        RM_REGISTER_SUCCESS = 1,
        RM_REGISTER_FAILED = 2,
        RM_REGISTER_RESULT = 3,
        
        // TM -> TC
        TM_REGISTER_SUCCESS = 4,
        TM_REGISTER_FAILED = 5,
        TM_REGISTER_RESULT = 6,
        
        // TM -> TC
        GLOBAL_BEGIN = 7,
        GLOBAL_BEGIN_RESULT = 8,
        
        // TM -> TC
        GLOBAL_COMMIT = 9,
        GLOBAL_COMMIT_RESULT = 10,
        
        // TM -> TC
        GLOBAL_ROLLBACK = 11,
        GLOBAL_ROLLBACK_RESULT = 12,
        
        // TM -> TC
        GLOBAL_STATUS = 13,
        GLOBAL_STATUS_RESULT = 14,
        
        // RM -> TC
        BRANCH_REGISTER = 15,
        BRANCH_REGISTER_RESULT = 16,
        
        // RM -> TC
        BRANCH_REPORT = 17,
        BRANCH_REPORT_RESULT = 18,
        
        // RM -> TC
        GLOBAL_LOCK_QUERY = 19,
        GLOBAL_LOCK_QUERY_RESULT = 20,
        
        // TC -> RM
        BRANCH_COMMIT = 21,
        BRANCH_COMMIT_RESULT = 22,
        
        // TC -> RM
        BRANCH_ROLLBACK = 23,
        BRANCH_ROLLBACK_RESULT = 24,
        
        // TC -> RM
        UNDO_LOG_DELETE = 25,
        UNDO_LOG_DELETE_RESULT = 26,
        
        // 心跳消息
        HEARTBEAT_REQUEST = 27,
        HEARTBEAT_RESPONSE = 28,
        
        // 其他
        MERGE = 29,
        MERGE_RESULT = 30,
        
        // 全局事务报告
        GLOBAL_REPORT = 31,
        GLOBAL_REPORT_RESULT = 32,

        // TCC事务
        TCC_ACTION_REQUEST = 33,
        TCC_ACTION_RESPONSE = 34,

        // 分支事务状态查询
        BRANCH_STATUS = 35,
        BRANCH_STATUS_RESULT = 36
    }

    /// <summary>
    /// Seata协议消息基类
    /// </summary>
    public abstract class AbstractMessage
    {
        public virtual MessageType MessageType { get; set; }

        public virtual int MessageCode { get; set; }

        public virtual string MessageId { get; set; } = Guid.NewGuid().ToString();

        public abstract byte[] Encode();

        public abstract void Decode(byte[] data);
    }

    /// <summary>
    /// 事务消息基类
    /// </summary>
    public abstract class TransactionMessage : AbstractMessage
    {
        public string Xid { get; set; }
        
        public long TransactionId { get; set; }
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
        }
    }

    /// <summary>
    /// 全局事务开始请求
    /// </summary>
    public class GlobalBeginRequest : AbstractMessage
    {
        public string TransactionName { get; set; }
        
        public int Timeout { get; set; }
        
        public override MessageType MessageType => MessageType.GLOBAL_BEGIN;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write(TransactionName ?? string.Empty);
            writer.Write(Timeout);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            TransactionName = reader.ReadString();
            Timeout = reader.ReadInt32();
        }
    }

    /// <summary>
    /// 全局事务开始响应
    /// </summary>
    public class GlobalBeginResponse : AbstractMessage
    {
        public string Xid { get; set; }

        public long TransactionId { get; set; }

        public GlobalStatus GlobalStatus { get; set; }

        public ResultCode ResultCode { get; set; }

        public string Message { get; set; }

        public Common.TransactionStatus TransactionStatus { get; set; }

        public string ErrorCode { get; set; }

        public string ErrorMessage { get; set; }

        public override MessageType MessageType => MessageType.GLOBAL_BEGIN_RESULT;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write((int)GlobalStatus);
            writer.Write((int)ResultCode);
            writer.Write(Message ?? string.Empty);
            writer.Write((int)TransactionStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            GlobalStatus = (GlobalStatus)reader.ReadInt32();
            ResultCode = (ResultCode)reader.ReadInt32();
            Message = reader.ReadString();
            TransactionStatus = (TransactionStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 全局事务提交请求
    /// </summary>
    public class GlobalCommitRequest : TransactionMessage
    {
        public override MessageType MessageType => MessageType.GLOBAL_COMMIT;
    }

    /// <summary>
    /// 全局事务提交响应
    /// </summary>
    public class GlobalCommitResponse : TransactionMessage
    {
        public GlobalStatus GlobalStatus { get; set; }

        public ResultCode ResultCode { get; set; }

        public string Message { get; set; }

        public Common.TransactionStatus TransactionStatus { get; set; }

        public string ErrorCode { get; set; }

        public string ErrorMessage { get; set; }

        public override MessageType MessageType => MessageType.GLOBAL_COMMIT_RESULT;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write((int)GlobalStatus);
            writer.Write((int)ResultCode);
            writer.Write(Message ?? string.Empty);
            writer.Write((int)TransactionStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            GlobalStatus = (GlobalStatus)reader.ReadInt32();
            ResultCode = (ResultCode)reader.ReadInt32();
            Message = reader.ReadString();
            TransactionStatus = (TransactionStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 全局事务回滚请求
    /// </summary>
    public class GlobalRollbackRequest : TransactionMessage
    {
        public override MessageType MessageType => MessageType.GLOBAL_ROLLBACK;
    }

    /// <summary>
    /// 全局事务回滚响应
    /// </summary>
    public class GlobalRollbackResponse : TransactionMessage
    {
        public GlobalStatus GlobalStatus { get; set; }

        public ResultCode ResultCode { get; set; }

        public string Message { get; set; }

        public Common.TransactionStatus TransactionStatus { get; set; }

        public string ErrorCode { get; set; }

        public string ErrorMessage { get; set; }

        public override MessageType MessageType => MessageType.GLOBAL_ROLLBACK_RESULT;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write((int)GlobalStatus);
            writer.Write((int)ResultCode);
            writer.Write(Message ?? string.Empty);
            writer.Write((int)TransactionStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            GlobalStatus = (GlobalStatus)reader.ReadInt32();
            ResultCode = (ResultCode)reader.ReadInt32();
            Message = reader.ReadString();
            TransactionStatus = (TransactionStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 全局事务状态查询请求
    /// </summary>
    public class GlobalStatusRequest : TransactionMessage
    {
        public override MessageType MessageType => MessageType.GLOBAL_STATUS;
    }

    /// <summary>
    /// 全局事务状态查询响应
    /// </summary>
    public class GlobalStatusResponse : TransactionMessage
    {
        public GlobalStatus GlobalStatus { get; set; }

        public ResultCode ResultCode { get; set; }

        public string ErrorCode { get; set; }

        public string ErrorMessage { get; set; }

        public override MessageType MessageType => MessageType.GLOBAL_STATUS_RESULT;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write((int)GlobalStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            GlobalStatus = (GlobalStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务注册请求
    /// </summary>
    public class BranchRegisterRequest : AbstractMessage
    {
        public string Xid { get; set; }

        public long TransactionId { get; set; }

        public BranchType BranchType { get; set; }

        public string ResourceId { get; set; }

        public string LockKey { get; set; }

        public string? ApplicationData { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_REGISTER;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write((int)BranchType);
            writer.Write(ResourceId ?? string.Empty);
            writer.Write(LockKey ?? string.Empty);
            writer.Write(ApplicationData ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            BranchType = (BranchType)reader.ReadInt32();
            ResourceId = reader.ReadString();
            LockKey = reader.ReadString();
            ApplicationData = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务注册响应
    /// </summary>
    public class BranchRegisterResponse : AbstractMessage
    {
        public long BranchId { get; set; }

        public ResultCode ResultCode { get; set; }

        public string Message { get; set; }

        public Common.TransactionStatus TransactionStatus { get; set; }

        public string ErrorCode { get; set; }

        public string ErrorMessage { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_REGISTER_RESULT;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(BranchId);
            writer.Write((int)ResultCode);
            writer.Write(Message ?? string.Empty);
            writer.Write((int)TransactionStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            BranchId = reader.ReadInt64();
            ResultCode = (ResultCode)reader.ReadInt32();
            Message = reader.ReadString();
            TransactionStatus = (TransactionStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务报告请求
    /// </summary>
    public class BranchReportRequest : AbstractMessage
    {
        public string Xid { get; set; }

        public long TransactionId { get; set; }

        public long BranchId { get; set; }

        public BranchType BranchType { get; set; }

        public BranchStatus BranchStatus { get; set; }

        /// <summary>
        /// 状态别名
        /// </summary>
        public BranchStatus Status
        {
            get => BranchStatus;
            set => BranchStatus = value;
        }

        public string ApplicationData { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_REPORT;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write(BranchId);
            writer.Write((int)BranchType);
            writer.Write((int)BranchStatus);
            writer.Write(ApplicationData ?? string.Empty);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            BranchId = reader.ReadInt64();
            BranchType = (BranchType)reader.ReadInt32();
            BranchStatus = (BranchStatus)reader.ReadInt32();
            ApplicationData = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务报告响应
    /// </summary>
    public class BranchReportResponse : AbstractMessage
    {
        public ResultCode ResultCode { get; set; }

        public string Message { get; set; }

        public Common.TransactionStatus TransactionStatus { get; set; }

        public string ErrorCode { get; set; }

        public string ErrorMessage { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_REPORT_RESULT;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write((int)ResultCode);
            writer.Write(Message ?? string.Empty);
            writer.Write((int)TransactionStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            ResultCode = (ResultCode)reader.ReadInt32();
            Message = reader.ReadString();
            TransactionStatus = (TransactionStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务状态查询请求
    /// </summary>
    public class BranchStatusRequest : AbstractMessage
    {
        public string Xid { get; set; }

        public long BranchId { get; set; }

        public BranchType BranchType { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_STATUS;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(BranchId);
            writer.Write((int)BranchType);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            BranchId = reader.ReadInt64();
            BranchType = (BranchType)reader.ReadInt32();
        }
    }

    /// <summary>
    /// 分支事务状态查询响应
    /// </summary>
    public class BranchStatusResponse : AbstractMessage
    {
        public BranchStatus BranchStatus { get; set; }

        /// <summary>
        /// Status别名，用于兼容性
        /// </summary>
        public BranchStatus Status
        {
            get => BranchStatus;
            set => BranchStatus = value;
        }

        public ResultCode ResultCode { get; set; }

        public string Message { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_STATUS_RESULT;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write((int)BranchStatus);
            writer.Write((int)ResultCode);
            writer.Write(Message ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            BranchStatus = (BranchStatus)reader.ReadInt32();
            ResultCode = (ResultCode)reader.ReadInt32();
            Message = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务提交请求
    /// </summary>
    public class BranchCommitRequest : AbstractMessage
    {
        public string Xid { get; set; }

        public long TransactionId { get; set; }

        public long BranchId { get; set; }

        public BranchType BranchType { get; set; }

        public string ResourceId { get; set; }

        public string ApplicationData { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_COMMIT;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write(BranchId);
            writer.Write((int)BranchType);
            writer.Write(ResourceId ?? string.Empty);
            writer.Write(ApplicationData ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            BranchId = reader.ReadInt64();
            BranchType = (BranchType)reader.ReadInt32();
            ResourceId = reader.ReadString();
            ApplicationData = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务提交响应
    /// </summary>
    public class BranchCommitResponse : AbstractMessage
    {
        public BranchStatus BranchStatus { get; set; }
        
        public string ErrorCode { get; set; }
        
        public string ErrorMessage { get; set; }
        
        public override MessageType MessageType => MessageType.BRANCH_COMMIT_RESULT;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write((int)BranchStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            BranchStatus = (BranchStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务回滚请求
    /// </summary>
    public class BranchRollbackRequest : AbstractMessage
    {
        public string Xid { get; set; }

        public long TransactionId { get; set; }

        public long BranchId { get; set; }

        public BranchType BranchType { get; set; }

        public string ResourceId { get; set; }

        public string ApplicationData { get; set; }

        public override MessageType MessageType => MessageType.BRANCH_ROLLBACK;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);

            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write(BranchId);
            writer.Write((int)BranchType);
            writer.Write(ResourceId ?? string.Empty);
            writer.Write(ApplicationData ?? string.Empty);

            return stream.ToArray();
        }

        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            BranchId = reader.ReadInt64();
            BranchType = (BranchType)reader.ReadInt32();
            ResourceId = reader.ReadString();
            ApplicationData = reader.ReadString();
        }
    }

    /// <summary>
    /// 分支事务回滚响应
    /// </summary>
    public class BranchRollbackResponse : AbstractMessage
    {
        public BranchStatus BranchStatus { get; set; }
        
        public string ErrorCode { get; set; }
        
        public string ErrorMessage { get; set; }
        
        public override MessageType MessageType => MessageType.BRANCH_ROLLBACK_RESULT;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write((int)BranchStatus);
            writer.Write(ErrorCode ?? string.Empty);
            writer.Write(ErrorMessage ?? string.Empty);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            BranchStatus = (BranchStatus)reader.ReadInt32();
            ErrorCode = reader.ReadString();
            ErrorMessage = reader.ReadString();
        }
    }

    /// <summary>
    /// 心跳请求
    /// </summary>
    public class HeartbeatRequest : AbstractMessage
    {
        public override MessageType MessageType => MessageType.HEARTBEAT_REQUEST;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
        }
    }

    /// <summary>
    /// 心跳响应
    /// </summary>
    public class HeartbeatResponse : AbstractMessage
    {
        public ResultCode ResultCode { get; set; } = ResultCode.Success;

        public override MessageType MessageType => MessageType.HEARTBEAT_RESPONSE;

        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
        }
    }

    /// <summary>
    /// 全局事务报告请求
    /// </summary>
    public class GlobalReportRequest : TransactionMessage
    {
        public string ApplicationId { get; set; }
        
        public string TransactionServiceGroup { get; set; }
        
        public override MessageType MessageType => MessageType.GLOBAL_REPORT;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write(Xid ?? string.Empty);
            writer.Write(TransactionId);
            writer.Write(ApplicationId ?? string.Empty);
            writer.Write(TransactionServiceGroup ?? string.Empty);
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            Xid = reader.ReadString();
            TransactionId = reader.ReadInt64();
            ApplicationId = reader.ReadString();
            TransactionServiceGroup = reader.ReadString();
        }
    }

    /// <summary>
    /// 全局事务报告响应
    /// </summary>
    public class GlobalReportResponse : AbstractMessage
    {
        public ResultCode ResultCode { get; set; }
        
        public string ErrorMessage { get; set; }
        
        public GlobalTransactionReport GlobalTransactionReport { get; set; }
        
        public override MessageType MessageType => MessageType.GLOBAL_REPORT_RESULT;
        
        public override byte[] Encode()
        {
            using var stream = new MemoryStream();
            using var writer = new BinaryWriter(stream);
            
            writer.Write((int)MessageType);
            writer.Write((int)ResultCode);
            writer.Write(ErrorMessage ?? string.Empty);
            
            if (GlobalTransactionReport != null)
            {
                var reportData = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(GlobalTransactionReport);
                writer.Write(reportData.Length);
                writer.Write(reportData);
            }
            else
            {
                writer.Write(0);
            }
            
            return stream.ToArray();
        }
        
        public override void Decode(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);
            
            MessageType = (MessageType)reader.ReadInt32();
            ResultCode = (ResultCode)reader.ReadInt32();
            ErrorMessage = reader.ReadString();
            
            var reportDataLength = reader.ReadInt32();
            if (reportDataLength > 0)
            {
                var reportData = reader.ReadBytes(reportDataLength);
                GlobalTransactionReport = System.Text.Json.JsonSerializer.Deserialize<GlobalTransactionReport>(reportData);
            }
        }
    }

    /// <summary>
    /// 全局事务报告
    /// </summary>
    public class GlobalTransactionReport
    {
        /// <summary>
        /// 全局事务ID
        /// </summary>
        public string Xid { get; set; }
        
        /// <summary>
        /// 事务状态
        /// </summary>
        public Common.TransactionStatus Status { get; set; }
        
        /// <summary>
        /// 应用ID
        /// </summary>
        public string ApplicationId { get; set; }
        
        /// <summary>
        /// 事务服务组
        /// </summary>
        public string TransactionServiceGroup { get; set; }
        
        /// <summary>
        /// 事务名称
        /// </summary>
        public string TransactionName { get; set; }
        
        /// <summary>
        /// 超时时间（毫秒）
        /// </summary>
        public int Timeout { get; set; }
        
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime BeginTime { get; set; }
        
        /// <summary>
        /// 应用数据
        /// </summary>
        public string ApplicationData { get; set; }
    }

    /// <summary>
    /// 协议消息工厂
    /// </summary>
    public static class MessageFactory
    {
        private static readonly Dictionary<MessageType, Type> _messageTypes = new()
        {
            { MessageType.GLOBAL_BEGIN, typeof(GlobalBeginRequest) },
            { MessageType.GLOBAL_BEGIN_RESULT, typeof(GlobalBeginResponse) },
            { MessageType.GLOBAL_COMMIT, typeof(GlobalCommitRequest) },
            { MessageType.GLOBAL_COMMIT_RESULT, typeof(GlobalCommitResponse) },
            { MessageType.GLOBAL_ROLLBACK, typeof(GlobalRollbackRequest) },
            { MessageType.GLOBAL_ROLLBACK_RESULT, typeof(GlobalRollbackResponse) },
            { MessageType.GLOBAL_STATUS, typeof(GlobalStatusRequest) },
            { MessageType.GLOBAL_STATUS_RESULT, typeof(GlobalStatusResponse) },
            { MessageType.GLOBAL_REPORT, typeof(GlobalReportRequest) },
            { MessageType.GLOBAL_REPORT_RESULT, typeof(GlobalReportResponse) },
            { MessageType.BRANCH_REGISTER, typeof(BranchRegisterRequest) },
            { MessageType.BRANCH_REGISTER_RESULT, typeof(BranchRegisterResponse) },
            { MessageType.BRANCH_REPORT, typeof(BranchReportRequest) },
            { MessageType.BRANCH_REPORT_RESULT, typeof(BranchReportResponse) },
            { MessageType.BRANCH_COMMIT, typeof(BranchCommitRequest) },
            { MessageType.BRANCH_COMMIT_RESULT, typeof(BranchCommitResponse) },
            { MessageType.BRANCH_ROLLBACK, typeof(BranchRollbackRequest) },
            { MessageType.BRANCH_ROLLBACK_RESULT, typeof(BranchRollbackResponse) },
            { MessageType.HEARTBEAT_REQUEST, typeof(HeartbeatRequest) },
            { MessageType.HEARTBEAT_RESPONSE, typeof(HeartbeatResponse) }
        };

        public static AbstractMessage CreateMessage(MessageType messageType)
        {
            if (_messageTypes.TryGetValue(messageType, out var type))
            {
                return (AbstractMessage)Activator.CreateInstance(type)!;
            }
            
            throw new NotSupportedException($"Message type {messageType} is not supported");
        }

        public static AbstractMessage DecodeMessage(byte[] data)
        {
            using var stream = new MemoryStream(data);
            using var reader = new BinaryReader(stream);

            var messageType = (MessageType)reader.ReadInt32();
            var message = CreateMessage(messageType);
            message.Decode(data);

            return message;
        }

        /// <summary>
        /// 获取消息类型
        /// </summary>
        /// <param name="message">消息对象</param>
        /// <returns>消息类型</returns>
        public static MessageType GetMessageType(AbstractMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            return message.MessageType;
        }
    }
}